package managedbean;

import entity.BranchEntity;
import entity.BranchAddressEntity;
import entity.BranchOperatingHoursEntity;
import entity.CuisinePrefEntity;
import entity.FnBBranchEntity;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import session.stateless.BranchSessionBean;
import util.enumeration.CuisineType;
import util.enumeration.FnbType;
import util.enumeration.OperatingHours;

@ManagedBean(name = "branchManagerBean")
@ViewScoped
public class BranchManagerBean implements Serializable {

    @EJB
    private BranchSessionBean branchSessionBean;
    /*------------------------------------------*/
    //-------------AddBranch.xhtml--------------//
    /*------------------------------------------*/
    private String branchName;
    private Long postalCode;
    private String houseNumber;
    private String streetName;
    private String buildingName = "";
    private String contactNumber;
    private String contactPerson;
    private String priceRange;
    private String isHalal;
    //opening hours
    private OperatingHours mondayStart;
    private OperatingHours tuesdayStart;
    private OperatingHours wednesdayStart;
    private OperatingHours thursdayStart;
    private OperatingHours fridayStart;
    private OperatingHours saturdayStart;
    private OperatingHours sundayStart;
    //closing hours
    private OperatingHours mondayEnd;
    private OperatingHours tuesdayEnd;
    private OperatingHours wednesdayEnd;
    private OperatingHours thursdayEnd;
    private OperatingHours fridayEnd;
    private OperatingHours saturdayEnd;
    private OperatingHours sundayEnd;
    //remarks
    private String remarks;
    //others
    private boolean branchAdded;
    private boolean branchExists;
    private List<BranchEntity> branchList;
    private String statusMessage;
    //protected List<OperatingHours> operatingHoursList = new ArrayList<OperatingHours>();
    private String button;
    //================Enumeration====================
    private FnbType fnbType;
    private List<CuisineType> selectedCuisine;
    private List<CuisineType> cuisineType;
    private Map<CuisineType, Boolean> selectedIds = new HashMap<CuisineType, Boolean>();
    /*------------------------------------------*/
    //----------ViewAllBranch.xhtml-------------//
    /*------------------------------------------*/
    private BranchEntity selectedBranch;
    
    
    private List<String> selectedCuisines;
    

    /*------------------------------------------*/
    //------------EditBranch.xhtml--------------//
    /*------------------------------------------*/
    public BranchManagerBean() {
        cuisineType = new ArrayList<CuisineType>();
        for (CuisineType ct : CuisineType.values()) {
            cuisineType.add(ct);
        }
    }

    public CuisineType[] getCuisineTypes() {
        return CuisineType.values();
    }

    public FnbType[] getFnbTypes() {
        return FnbType.values();
    }

    public OperatingHours[] getOperatingHours() {
        return OperatingHours.values();
    }

    public FnbType getFnbType() {
        return fnbType;
    }

    public void setFnbType(FnbType fnbType) {
        this.fnbType = fnbType;
    }

    public List<CuisineType> getCuisineType() {
        return cuisineType;
    }

    public void setCuisineType(List<CuisineType> cuisineType) {
        this.cuisineType = cuisineType;
    }

    public String getBranchName() {
        return branchName;
    }

    public void setBranchName(String branchName) {
        this.branchName = branchName;
    }

    public Long getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(Long postalCode) {
        this.postalCode = postalCode;
    }

    public String getHouseNumber() {
        return houseNumber;
    }

    public void setHouseNumber(String houseNumber) {
        this.houseNumber = houseNumber;
    }

    public String getStreetName() {
        return streetName;
    }

    public void setStreetName(String streetName) {
        this.streetName = streetName;
    }

    public String getBuildingName() {
        return buildingName;
    }

    public void setBuildingName(String buildingName) {
        this.buildingName = buildingName;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getContactPerson() {
        return contactPerson;
    }

    public void setContactPerson(String contactPerson) {
        this.contactPerson = contactPerson;
    }

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }

    public BranchEntity getSelectedBranch() {
        return selectedBranch;
    }

    public void setSelectedBranch(BranchEntity selectedBranch) {
        this.selectedBranch = selectedBranch;
    }

    public String getPriceRange() {
        return priceRange;
    }

    public void setPriceRange(String priceRange) {
        this.priceRange = priceRange;
    }

    public String getIsHalal() {
        return isHalal;
    }

    public void setIsHalal(String isHalal) {
        this.isHalal = isHalal;
    }

    public Map<CuisineType, Boolean> getSelectedIds() {
        return selectedIds;
    }

    public OperatingHours getMondayStart() {
        return mondayStart;
    }

    public void setMondayStart(OperatingHours mondayStart) {
        this.mondayStart = mondayStart;
    }

    public OperatingHours getTuesdayStart() {
        return tuesdayStart;
    }

    public void setTuesdayStart(OperatingHours tuesdayStart) {
        this.tuesdayStart = tuesdayStart;
    }

    public OperatingHours getWednesdayStart() {
        return wednesdayStart;
    }

    public void setWednesdayStart(OperatingHours wednesdayStart) {
        this.wednesdayStart = wednesdayStart;
    }

    public OperatingHours getThursdayStart() {
        return thursdayStart;
    }

    public void setThursdayStart(OperatingHours thursdayStart) {
        this.thursdayStart = thursdayStart;
    }

    public OperatingHours getFridayStart() {
        return fridayStart;
    }

    public void setFridayStart(OperatingHours fridayStart) {
        this.fridayStart = fridayStart;
    }

    public OperatingHours getSaturdayStart() {
        return saturdayStart;
    }

    public void setSaturdayStart(OperatingHours saturdayStart) {
        this.saturdayStart = saturdayStart;
    }

    public OperatingHours getSundayStart() {
        return sundayStart;
    }

    public void setSundayStart(OperatingHours sundayStart) {
        this.sundayStart = sundayStart;
    }

    public OperatingHours getMondayEnd() {
        return mondayEnd;
    }

    public void setMondayEnd(OperatingHours mondayEnd) {
        this.mondayEnd = mondayEnd;
    }

    public OperatingHours getTuesdayEnd() {
        return tuesdayEnd;
    }

    public void setTuesdayEnd(OperatingHours tuesdayEnd) {
        this.tuesdayEnd = tuesdayEnd;
    }

    public OperatingHours getWednesdayEnd() {
        return wednesdayEnd;
    }

    public void setWednesdayEnd(OperatingHours wednesdayEnd) {
        this.wednesdayEnd = wednesdayEnd;
    }

    public OperatingHours getThursdayEnd() {
        return thursdayEnd;
    }

    public void setThursdayEnd(OperatingHours thursdayEnd) {
        this.thursdayEnd = thursdayEnd;
    }

    public OperatingHours getFridayEnd() {
        return fridayEnd;
    }

    public void setFridayEnd(OperatingHours fridayEnd) {
        this.fridayEnd = fridayEnd;
    }

    public OperatingHours getSaturdayEnd() {
        return saturdayEnd;
    }

    public void setSaturdayEnd(OperatingHours saturdayEnd) {
        this.saturdayEnd = saturdayEnd;
    }

    public OperatingHours getSundayEnd() {
        return sundayEnd;
    }

    public void setSundayEnd(OperatingHours sundayEnd) {
        this.sundayEnd = sundayEnd;
    }

    //========================= ADD BRANCH.XHTML ========================= \\
    /*-------------------------- Add F&B BranchEntity ---------------------- */
    public void saveBranch() {
        try {
            int postal = Integer.parseInt(getPostalCode().toString());

            selectedCuisine = new ArrayList<CuisineType>();
            for (CuisineType cuisine : getCuisineType()) {
                if (selectedIds.get(cuisine)) {
                    selectedCuisine.add(cuisine);
                    selectedIds.remove(cuisine); // Reset.
                }
            }

            //set the operating hours into a list
            /*
            OperatingHours monHrs = new OperatingHours("Monday", getMondayStart(), getMondayEnd());
            OperatingHours tuesHrs = new OperatingHours("Tuesday", getTuesdayStart(), getMondayEnd());
            OperatingHours wedHrs = new OperatingHours("Wednesday", getWednesdayStart(), getWednesdayEnd());
            OperatingHours thursHrs = new OperatingHours("Thursday", getThursdayStart(), getThursdayEnd());
            OperatingHours friHrs = new OperatingHours("Friday", getFridayStart(), getFridayEnd());
            OperatingHours satHrs = new OperatingHours("Saturday", getSaturdayStart(), getSaturdayEnd());
            OperatingHours sunHrs = new OperatingHours("Sunday", getSundayStart(), getSundayEnd());
             */

            //addBranch method from session bean
            branchAdded = branchSessionBean.addBranch(getBranchName(), postal, getHouseNumber(), getStreetName(), getBuildingName(), getContactNumber(), getContactPerson(), getFnbType(), getIsHalal(), getPriceRange(), getRemarks(), selectedCuisine);
            if (branchAdded == true) {
                statusMessage = "Branch is added successfully";
            } else {
                statusMessage = "Branch portal is not added";
            }
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, ""));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void getFnBBranchList() {
        try {
            //getBranchRecord
            List<FnBBranchEntity> branchList = branchSessionBean.getFnBBranchList();
            if (branchList.size() > 0) {
                branchExists = true;
            } else {
                branchExists = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<BranchEntity> getBranchList() {
        List<BranchEntity> branchList = new ArrayList();
        try {
            //getBranchRecord
            branchList = branchSessionBean.viewAllBranch();
            if (branchList.size() > 0) {
                branchExists = true;
            } else {
                branchExists = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return branchList;
    }

    public String getButton() {
        getBranchList();
        if (branchExists == true) {
            return "Add More Branches";
        } else {
            return "Add Branches";
        }
    }

    /*
    public void validateFnBType() {
    if (getFnbType().name().equals(getFnbType().SELECT)) {
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "FnB Type is Required.", ""));
    }
    }
    
    public void validatePriceRange() {
    if (getPriceRange().equals("Select")) {
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Price Range is Required.", ""));
    }
    }
     */
    //=========== VIEW ALL BRANCH.XHTML =============== \\
    private SelectItem[] createFilterOptions(String[] data) {
        SelectItem[] options = new SelectItem[data.length + 1];

        options[0] = new SelectItem("", "Select");
        for (int i = 0; i < data.length; i++) {
            options[i + 1] = new SelectItem(data[i], data[i]);
        }

        return options;
    }

    //=========== EDITBRANCH.XHTML =============== \\
    public void view_Edit_Branch(BranchEntity selectedBranch) throws IOException
    {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedBranch", selectedBranch);
        FacesContext.getCurrentInstance().getExternalContext().redirect("EditBranch.xhtml");
    }

    public List<BranchAddressEntity> view_Branch_Address() {
        getSelectedBranch();
        for (BranchAddressEntity ba : branchSessionBean.viewBranchAddress(selectedBranch)) {
            setHouseNumber(ba.getHouseNumber());
            setStreetName("Jurong");
        }
        return branchSessionBean.viewBranchAddress(selectedBranch);

    }

    public List<FnBBranchEntity> view_FnB_Branch(ActionEvent evt) {
        BranchEntity b = (BranchEntity) evt.getComponent().getAttributes().get("branch");
        return branchSessionBean.viewFnBBranch(b);
    }

    public List<BranchOperatingHoursEntity> view_Operating_Hours(ActionEvent evt) {
        BranchEntity b = (BranchEntity) evt.getComponent().getAttributes().get("branch");
        return branchSessionBean.viewBranchOperatingHours(b);
    }

    public List<CuisinePrefEntity> view_Cuisine_Pref(ActionEvent evt) {
        BranchEntity b = (BranchEntity) evt.getComponent().getAttributes().get("branch");
        return branchSessionBean.viewCuisinePref(b);
    }

    public SelectItem[] getCuisineTypeValues() {
        
        SelectItem[] selectItems = new SelectItem[14];
        selectItems[0] = new SelectItem(CuisineType.CANTONESE.toString(), CuisineType.CANTONESE.toString());
        selectItems[1] = new SelectItem(CuisineType.CHINESE.toString(), CuisineType.CHINESE.toString());
        selectItems[2] = new SelectItem(CuisineType.FUJIAN.toString(), CuisineType.FUJIAN.toString());
        selectItems[3] = new SelectItem(CuisineType.HAINANESE.toString(), CuisineType.HAINANESE.toString());
        selectItems[4] = new SelectItem(CuisineType.HAKKA.toString(), CuisineType.HAKKA.toString());
        selectItems[5] = new SelectItem(CuisineType.HOKKIEN.toString(), CuisineType.HOKKIEN.toString());
        selectItems[6] = new SelectItem(CuisineType.INDIAN.toString(), CuisineType.INDIAN.toString());
        selectItems[7] = new SelectItem(CuisineType.JAPANESE.toString(), CuisineType.JAPANESE.toString());
        selectItems[8] = new SelectItem(CuisineType.KOREAN.toString(), CuisineType.KOREAN.toString());
        selectItems[9] = new SelectItem(CuisineType.MALAY.toString(), CuisineType.MALAY.toString());
        selectItems[10] = new SelectItem(CuisineType.SHANGHAI.toString(), CuisineType.SHANGHAI.toString());
        selectItems[11] = new SelectItem(CuisineType.TEOCHEW.toString(), CuisineType.TEOCHEW.toString());
        selectItems[12] = new SelectItem(CuisineType.WESTERN.toString(), CuisineType.WESTERN.toString());
        selectItems[13] = new SelectItem(CuisineType.XINJIANG.toString(), CuisineType.XINJIANG.toString());

        return selectItems;
    }

    public List<CuisineType> getSelectedCuisine() {
        return selectedCuisine;
    }

    public void setSelectedCuisine(List<CuisineType> selectedCuisine) {
        this.selectedCuisine = selectedCuisine;
    }

    public List<String> getSelectedCuisines() {
        return selectedCuisines;
    }

    public void setSelectedCuisines(List<String> selectedCuisines) {
        this.selectedCuisines = selectedCuisines;
    }

}